package com.tengju.user.infrastructure.repository;

import com.tengju.user.application.shared.Constant;
import com.tengju.user.domain.model.login.LoginResult;
import com.tengju.user.domain.model.login.UserAccount;
import com.tengju.user.domain.model.login.UserAccountId;
import com.tengju.user.domain.model.login.UserType;
import com.tengju.user.domain.model.user.UserAccountRepository;
import com.tengju.user.domain.model.user.UserId;
import com.tengju.user.domain.shared.IdObject;
import com.tengju.user.infrastructure.persistence.mybatis.dataobject.UserAccountDO;
import com.tengju.user.infrastructure.persistence.mybatis.mapper.dealer.custom.UserAccountDOCustomMapper;
import com.tengju.user.infrastructure.persistence.redis.LoginTokenCacheRepository;
import com.tengju.user.infrastructure.repository.convert.UserAccountConvert;
import com.tengju.user.infrastructure.shared.InfraException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

/**
 * @author wuziyang
 */
@Repository
public class UserAccountRepositoryImpl implements UserAccountRepository {

    @Resource
    UserAccountDOCustomMapper userAccountDOCustomMapper;

    @Autowired
    LoginTokenCacheRepository tokenCacheRepository;


    @Override
    public UserAccount queryUserAccount(String userName, UserType userType) {

        UserAccountDO userAccountDO = userAccountDOCustomMapper
                .selectByUsernamAndUserType(userName,userName + "", userType.getVal());

        return UserAccountConvert.convertUserDOToUser(userAccountDO);

    }

    @Override
    public UserAccount queryUserAccount(UserType userType, IdObject outId) {
        UserAccountDO userAccountDO = userAccountDOCustomMapper
                .selectByUserTypeAndOutId(userType.getVal(), outId.getValue());
        return UserAccountConvert.convertUserDOToUser(userAccountDO);
    }

    @Override
    public UserAccountId store(UserAccount userAccount) {

        UserAccountDO userAccountDO = UserAccountConvert.convertUserAccountToDO(userAccount);
        userAccountDO.setVersion(0L);
        userAccountDO.setCreateTime(new Date());
        userAccountDO.setUpdateTime(new Date());

        long userAccountId = userAccountDOCustomMapper.insert(userAccountDO);

        return new UserAccountId(userAccountId);
    }

    @Override
    public boolean saveToken(String token, String tokenData) {
        return tokenCacheRepository.cacheToken(token,tokenData, Constant.LOGIN_TOKEN_EXPIRE_TIME);
    }

    @Override
    public LoginResult getTokenValue(String key) {
        return tokenCacheRepository.getToken(key);
    }

    @Override
    public boolean delToken(String key) {

        return tokenCacheRepository.delToken(key);
    }

    @Override
    public boolean delPwdChangeToken(UserType userType, String areaCode, String mobile) {

        return tokenCacheRepository.delPwdChangeToken(userType,areaCode,mobile);

    }

    @Override
    public boolean changePwd(UserAccount userAccount) {
        UserAccountDO userAccountDO = UserAccountConvert.convertUserAccountToDO(userAccount);
        userAccountDO.setUpdateTime(Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant()));
        return userAccountDOCustomMapper.updatePwd(userAccountDO) == 1;
    }

    @Override
    public void changeUsername(UserAccount userAccount) {
        UserAccountDO userAccountDO = UserAccountConvert.convertUserAccountToDO(userAccount);
        UserAccountDO accountDO = userAccountDOCustomMapper
                .selectByUsernamAndUserType(userAccountDO.getUsername(),userAccountDO.getUsername() + "", UserType.USER.getVal());
        if (accountDO != null) {
            throw new InfraException("改手机号已注册");
        }
        if (userAccountDOCustomMapper.updateUsername(userAccountDO) != 1) {
            throw new InfraException("变更用户名失败");
        }
    }

    @Override
    public boolean login(UserAccount userAccount) {
        UserAccountDO userAccountDO = UserAccountConvert.convertUserAccountToDO(userAccount);
        return userAccountDOCustomMapper.updateLoginTime(userAccountDO) == 1;
    }

    @Override
    public int countTotal(UserType userType) {
        return userAccountDOCustomMapper.countTotal(userType.getVal());
    }

    @Override
    public int countNew(UserType userType,LocalDateTime from,LocalDateTime to) {
        return userAccountDOCustomMapper.countNew(userType.getVal(),from,to);
    }

    @Override
    public void deleteByUserId(UserType userType,UserId userId) {
        userAccountDOCustomMapper.deleteByOutId(userType.getVal(), userId.getValue());
    }

}
